﻿using Infragistics.Win.UltraMessageBox;
using Infragistics.Win.UltraWinGrid;
using OrBitDataModule.Dialog;
using OrBitDataModule;
using OrBitDataModule.Base;
using OrBitDataModule.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Alternet.Common;
using OrBitDataModule.Contract;
using OrBitDataModule.Common;
using DebuggerIntegration;
using System.IO;
using System.Diagnostics;
using OrBitDataModule.Adaptor;
using OrBitDataModule.CustomEventHandler;
using System.Net;
using Newtonsoft.Json;
using System.Collections.Specialized;
using Newtonsoft.Json.Linq;
using System.Windows.Markup;
using OrBitDataModule.ScripterDebugger;
using OrBitDataModule.Extensions;

namespace OrBitDataModule.Controls
{
    public partial class RunningTaskManager : UserControl
    {
        private TaskService Service = null;
        //private ScriptDebugger codeDebugger = null;

        private DebuggerForm codeDebugger = null;

        private List<TaskModel> tasksList = null;

        private QuartzScheduler Scheduler = null;

        private DateTime startTime = DateTime.Now;
        /// <summary>
        /// 监听http服务
        /// </summary>
        private HttpServer httpServer = null;
        public RunningTaskManager()
        {
            Service = new TaskService();
            InitializeComponent();
            InitRunningTask();
            Service.OnMessage += Service_OnMessage;
            Service.OnTaskStatusChange += Service_OnTaskStatusChange;
            codeDebugger = new DebuggerForm
            {
                TopLevel = false,
                Dock = DockStyle.Fill,
                FormBorderStyle = FormBorderStyle.None
            };
            ultraTabPageControl_ScriptDebug.Controls.Add(codeDebugger);
            codeDebugger.Show();
            ultraGrid_taskList.ClickCell += UltraGrid_taskList_ClickCell;
            InitControlText();
        }

        async void InitControlText()
        {
            toolStripStatusLabel_UserName.Text = SharedData.LoginUserName;
            Scheduler = new QuartzScheduler();
            await Scheduler.AddTaskBySecond(1, new Action(() =>
            {
                // 计算运行时间
                TimeSpan duration = DateTime.Now - startTime;
                this.BeginInvoke(new Action(() => { toolStripStatusLabel_RunningTime.Text = $"已运行时长：{duration.ToString(@"dd\.hh\:mm\:ss")}"; }));
            }));
            toolStripStatusLabel_HttpServer.Text = $"Http服务已启动，端口:{ConfigHelper.GetValue("HttpServerPort")}";
            Scheduler.Start();

            //启动http服务
            httpServer = new HttpServer(int.Parse(ConfigHelper.GetValue("HttpServerPort")));
            httpServer.OnHttpRequest += HttpServer_OnHttpRequest;
            httpServer.StartHttpServer();
        }

        private void HttpServer_OnHttpRequest(object sender, HttpRequestEventArgs e)
        {
            HttpListenerRequest request = e.Request;
            HttpListenerResponse response = e.Response;
            string ip = request.RemoteEndPoint.Address.ToString();
            try
            {
                string taskName = string.Empty;
                string action = string.Empty;

                if (request.HttpMethod == "POST")
                {
                    var form = request.ParseForm(Encoding.UTF8);

                    taskName = form["TaskName"];
                    action = form["Action"];
                    if (string.IsNullOrWhiteSpace(taskName))
                    {
                        HttpResponseWrite(response, JsonConvert.SerializeObject(new { IsSuccess = false, ReturnMessage = "TaskName参数为空", Data = Array.Empty<string>() }));
                        WriteLog($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}| 接收到来自IP：{ip},任务:{taskName},来自Http服务的请求。处理失败：TaskName参数为空");
                        return;
                    }
                    //if (string.IsNullOrWhiteSpace(action))
                    //{
                    //    HttpResponseWrite(response, JsonConvert.SerializeObject(new { result = false, ReturnMessage = "Action参数为空", Data = Array.Empty<string>() }));
                    //    return;
                    //}
                    TaskModel taskModel = tasksList.FirstOrDefault(t => t.TaskName.Equals(taskName, StringComparison.OrdinalIgnoreCase));
                    if (taskModel != null)
                    {
                        if (taskModel.Status != TaskRunningStatus.Started)
                        {
                            HttpResponseWrite(response, JsonConvert.SerializeObject(new { IsSuccess = false, ReturnMessage = "任务处于停止状态", Data = Array.Empty<string>() }));
                            WriteLog($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}| 接收到来自IP：{ip},任务:{taskName},来自Http服务的请求。处理失败：任务处于停止状态");
                            return;
                        }
                        string recived = taskModel.DataTask?.SendExternal(action);
                        HttpResponseWrite(response, recived);
                        WriteLog($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}| 接收到来自IP：{ip},任务:{taskName},来自Http服务的请求。已完成处理");
                    }
                    else
                    {
                        HttpResponseWrite(response, JsonConvert.SerializeObject(new { IsSuccess = false, ReturnMessage = "任务不存在", Data = Array.Empty<string>() }));
                        WriteLog($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}| 接收到来自IP：{ip},任务:{taskName},来自Http服务的请求。处理失败：任务不存在");
                        return;
                    }
                }


                //NameValueCollection form = request.ParseForm(Encoding.UTF8);
                //taskName = form["taskName"];
                //action = form["action"];
                //TaskModel taskModel = tasksList.FirstOrDefault(t => t.TaskName.Equals(taskName,StringComparison.OrdinalIgnoreCase));
                //if (taskModel != null)
                //{
                //    if (taskModel.Status != TaskRunningStatus.Started)
                //    {
                //        HttpResponseWrite(response, JsonConvert.SerializeObject(new { result = false, msg = "任务处于停止状态", response = "" }));
                //        return;
                //    }
                //    string recived = taskModel.DataTask?.SendExternal(action);
                //    HttpResponseWrite(response, JsonConvert.SerializeObject(new { result = true, msg = "", response = recived }));
                //}
                //else
                //{
                //    HttpResponseWrite(response, JsonConvert.SerializeObject(new { result = false, msg = "任务不存在", response = "" }));
                //    return;
                //}
                else
                {
                    HttpResponseWrite(response, JsonConvert.SerializeObject(new { IsSuccess = false, ReturnMessage = "只允许POST提交", Data = Array.Empty<string>() }));
                    WriteLog($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}| 接收到来自IP：{ip},处理失败：只允许POST提交");
                    return;
                }
            }
            catch (Exception ex)
            {
                HttpResponseWrite(response, JsonConvert.SerializeObject(new
                {
                    IsSuccess = false,
                    ReturnMessage = ex.Message,
                    Data = Array.Empty<string>()
                }));
                WriteLog($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}| 接收到来自IP：{ip},出现异常：{ex.ToString()}");
            }
        }

        void HttpResponseWrite(HttpListenerResponse response, string content)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(content);
            response.ContentLength64 = buffer.Length;
            response.ContentType = "application/json";
            using (Stream output = response.OutputStream)
            {
                output.Write(buffer, 0, buffer.Length);
                output.Close();
            }
        }


        /// <summary>
        /// 窗口关闭时停止所有任务
        /// </summary>
        public void Close()
        {
            Service.StopAllTask();
            Scheduler?.Shutdown();
        }

        private void UltraGrid_taskList_ClickCell(object sender, ClickCellEventArgs e)
        {
            string uniqueId = e.Cell.Row.GetCellValue("UniqueId").ToString();
            SetSelectRowRunningStatus(uniqueId);
        }

        /// <summary>
        /// 初始化当前任务数据，注册事件等
        /// </summary>
        private async void InitRunningTask()
        {
            btn_addTask.Click += Btn_addTask_Click;
            btn_removeTask.Click += Btn_removeTask_Click;
            btn_runTask.Click += Btn_runTask_Click;

            if (Service.TaskList == null || Service.TaskList.Count == 0)
            {
                _ = await Service.InitAllTask();
            }
            var localSetting = LocalSetting.GetAllConfigs();
            AutoStartTask(Service.TaskList, localSetting);
            ultraGrid_taskList.DoubleClickCell += UltraGrid_taskList_DoubleClickCell;
            GetAllTask();
        }

        private async void Btn_debug_Click(object sender, EventArgs e)
        {
            UltraGridRow selectedRow = ultraGrid_taskList.ActiveRow;
            if (selectedRow != null)
            {
                string uniqueId = selectedRow.Cells["UniqueId"].Value?.ToString();
                string DataProtocolScriptId = selectedRow.Cells["DataProtocolScriptId"].Value?.ToString();
                string taskName = selectedRow.Cells["TaskName"].Value?.ToString();

                TaskRunningStatus status = GetTaskRunningStatus(uniqueId);
                //if (GetTaskIsRunning(uniqueId))
                if (status == TaskRunningStatus.Started || status == TaskRunningStatus.Starting)
                {
                    UltraMessageBoxManager.Show(this, "该任务正在运行中，不允许调试！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (string.IsNullOrWhiteSpace(DataProtocolScriptId))
                {
                    UltraMessageBoxManager.Show(this, "该任务没有脚本，无法调试！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                var (ScriptName, ScriptCode, ScriptDescription, _) = await ScriptApi.GetCodeAsync(DataProtocolScriptId);
                string scriptName = ScriptName;
                string scriptCode = ScriptCode;
                string scriptDescription = ScriptDescription;
                if (string.IsNullOrWhiteSpace(scriptCode))
                {
                    UltraMessageBoxManager.Show(this, "该任务脚本代码为空，无法调试！", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                    return;
                }
                codeDebugger.LoadScript(uniqueId, taskName, scriptName, scriptCode, DataProtocolScriptId, scriptDescription, SharedData.LoginUserName, SharedData.LoginUserPassword);
                ultraTabControl_task.SelectedTab = ultraTabControl_task.Tabs[1];
            }
            else
            {
                UltraMessageBoxManager.Show(this, "未选中行！！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void UltraGrid_taskList_DoubleClickCell(object sender, DoubleClickCellEventArgs e)
        {
            string uniqueId = e.Cell.Row.GetCellValue("UniqueId").ToString();
            string taskName = e.Cell.Row.GetCellValue("taskName").ToString();
            using (AddRunningTask addRunningTask = new AddRunningTask(true, uniqueId, taskName))
            {
                if (addRunningTask.ShowDialog() == DialogResult.OK)
                {
                    bool autoStart = addRunningTask.AutoStart;
                    LocalSetting.UpdateConfig(uniqueId, autoStart, addRunningTask.Parameters);
                    //await GetAllTask();
                }
            }
        }

        /// <summary>
        /// 启动自动运行的任务
        /// </summary>
        /// <param name="tasks"></param>
        /// <param name="localSetting"></param>
        private void AutoStartTask(List<TaskModel> tasks, List<(string uniqueId, bool autoStart, Dictionary<string, string> parameters)> localSetting)
        {
            var autoRunTask = tasks.Where(t => localSetting.Any(l => l.autoStart && l.uniqueId.Equals(t.UniqueId))).ToList();
            autoRunTask.ForEach((task) =>
            {
                StartTask(task.UniqueId);
            });
        }

        /// <summary>
        /// 获取所有任务
        /// </summary>
        /// <returns></returns>
        private void GetAllTask()
        {
            var localSetting = LocalSetting.GetAllConfigs();
            tasksList = Service.TaskList.Where(k => localSetting.Any(c => c.uniqueId.Equals(k.UniqueId))).ToList();
            ultraGrid_taskList.DataSource = tasksList;
            ultraGrid_taskList.DataBind();
            RefreshGridTaskStatus();
            LocalSetting.CleanOrphanData(tasksList.Select(s => s.UniqueId).ToList());
        }

        /// <summary>
        /// 新增一行
        /// </summary>
        /// <param name="jobKey"></param>
        /// <param name="jobName"></param>
        /// <param name="jobScheduleName"></param>
        /// <param name="startTime"></param>
        private async void AddRow(string uniqueId)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(uniqueId))
                {
                    var result = await TaskApi.GetTaskById(uniqueId);
                    if (result.Result)
                    {
                        ultraGrid_taskList.Invoke(new Action(() =>
                        {
                            TaskModel taskModel = result.TaskModel;
                            tasksList.Add(taskModel);
                            // 更新
                            if (!Service.TaskList.Exists(t => t.UniqueId.Equals(taskModel.UniqueId)))
                            {
                                Service.TaskList.Add(taskModel);
                            }
                            ultraGrid_taskList.DataBind();
                            RefreshGridTaskStatus();
                        }));
                    }
                    else
                    {
                        UltraMessageBoxManager.Show(this, $"添加失败！信息:{result.Message}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message, true);
            }
        }

        private void RefreshGridTaskStatus()
        {
            foreach (UltraGridRow row in ultraGrid_taskList.Rows)
            {
                if (row.Cells["UniqueId"].Value == null && string.IsNullOrWhiteSpace(row.Cells["UniqueId"].Value.ToString()))
                {
                    row.Cells["TaskStatus"].Value = "停止";
                }
                else
                {
                    string uniqueId = row.Cells["UniqueId"].Value.ToString();
                    TaskRunningStatus status = GetTaskRunningStatus(uniqueId);
                    if (status == TaskRunningStatus.Starting)
                    {
                        row.Cells["TaskStatus"].Value = "正在启动";
                    }
                    else if (status == TaskRunningStatus.Started)
                    {
                        row.Cells["TaskStatus"].Value = "运行中";
                    }
                    else if (status == TaskRunningStatus.Stopping)
                    {
                        row.Cells["TaskStatus"].Value = "停止中";
                    }
                    else if (status == TaskRunningStatus.Stoped)
                    {
                        row.Cells["TaskStatus"].Value = "停止";
                    }
                    SetSelectRowRunningStatus(uniqueId);
                }
            }
        }

        /// <summary>
        /// 删除行
        /// </summary>
        /// <param name="jobKey"></param>
        private void DeleteRow(string uniqueId)
        {
            try
            {
                ultraGrid_taskList.Invoke(new Action(() =>
                {
                    if (tasksList.Any(t => t.UniqueId.Equals(uniqueId)))
                    {
                        this.tasksList.Remove(tasksList.FirstOrDefault(t => t.UniqueId.Equals(uniqueId)));
                        ultraGrid_taskList.Refresh();
                        RefreshGridTaskStatus();
                    }
                }));
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message, true);
            }
        }


        private void Btn_addTask_Click(object sender, EventArgs e)
        {
            using (AddRunningTask addRunningTask = new AddRunningTask(false, string.Empty, string.Empty))
            {
                if (addRunningTask.ShowDialog() == DialogResult.OK)
                {
                    string uniqueId = addRunningTask.UniqueId;
                    bool autoStart = addRunningTask.AutoStart;
                    AddRow(uniqueId);
                    LocalSetting.UpdateConfig(uniqueId, autoStart, addRunningTask.Parameters);
                }
            }
        }
        private void Btn_removeTask_Click(object sender, EventArgs e)
        {
            UltraGridRow selectedRow = ultraGrid_taskList.ActiveRow;
            if (selectedRow != null)
            {
                string uniqueId = selectedRow.Cells["UniqueId"].Value?.ToString();
                if (!string.IsNullOrWhiteSpace(uniqueId))
                {
                    if (UltraMessageBoxManager.Show(this, "确定要删除选中项？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
                    {
                        TaskRunningStatus status = GetTaskRunningStatus(uniqueId);
                        if (status == TaskRunningStatus.Started || status == TaskRunningStatus.Starting)
                        {
                            UltraMessageBoxManager.Show(this, "选择的项正在运行中，不允许删除！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                        var result = LocalSetting.RemoveConfig(uniqueId);
                        DeleteRow(uniqueId);
                        UltraMessageBoxManager.Show(this, result ? "删除成功！" : "删除失败！", result ? "提示" : "错误", MessageBoxButtons.OK, result ? MessageBoxIcon.Information : MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void Btn_runTask_Click(object sender, EventArgs e)
        {
            UltraGridRow selectedRow = ultraGrid_taskList.ActiveRow;
            if (selectedRow != null)
            {
                string uniqueId = selectedRow.Cells["UniqueId"].Value?.ToString();
                if (!string.IsNullOrWhiteSpace(uniqueId))
                {
                    TaskRunningStatus status = GetTaskRunningStatus(uniqueId);
                    //if (GetTaskIsRunning(uniqueId))
                    if (status == TaskRunningStatus.Started || status == TaskRunningStatus.Starting)
                    {
                        StopTask(uniqueId);
                    }
                    else
                    {
                        StartTask(uniqueId);
                    }
                }
            }
        }

        private void Service_OnTaskStatusChange(object sender, TaskEventArgs e)
        {
            tasksList.FirstOrDefault(t => t.UniqueId.Equals(e.UniqueId)).Status = e.Status;
            if (this.IsHandleCreated)
            {
                this.BeginInvoke(new Action(() =>
                {
                    foreach (var item in ultraGrid_taskList.Rows)
                    {
                        if (item.Cells["UniqueId"].Value.ToString() == e.UniqueId)
                        {

                            if (e.Status == TaskRunningStatus.Starting)
                            {
                                item.Cells["TaskStatus"].Value = "正在启动";
                                btn_runTask.Enabled = false;
                            }
                            else if (e.Status == TaskRunningStatus.Started)
                            {
                                item.Cells["TaskStatus"].Value = "运行中";
                                btn_runTask.Enabled = true;
                            }
                            else if (e.Status == TaskRunningStatus.Stopping)
                            {
                                item.Cells["TaskStatus"].Value = "停止中";
                                btn_runTask.Enabled = false;
                            }
                            else if (e.Status == TaskRunningStatus.Stoped)
                            {
                                item.Cells["TaskStatus"].Value = "停止";
                                btn_runTask.Enabled = true;
                            }
                            SetSelectRowRunningStatus(e.UniqueId);
                            return;
                        }
                    }
                }));
            }

        }

        private void Service_OnMessage(object sender, string e) => WriteLog(e);


        /// <summary>
        /// 设置任务运行状态
        /// </summary>
        /// <param name="uniqueId"></param>
        private void SetSelectRowRunningStatus(string uniqueId)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (this.IsHandleCreated)
                {
                    UltraGridRow selectedRow = ultraGrid_taskList.ActiveRow;
                    if (selectedRow != null)
                    {
                        string selectRowUniqueId = selectedRow.Cells["UniqueId"].Value?.ToString();
                        if (selectRowUniqueId.Equals(uniqueId))
                        {
                            TaskRunningStatus state = Service.GetTaskStatus(uniqueId);
                            if (state == TaskRunningStatus.Starting)
                            {
                                btn_runTask.Image = Properties.Resource.停止;
                                btn_runTask.Enabled = false;
                                btn_runTask.Text = "停止";
                            }
                            else if (state == Base.TaskRunningStatus.Started)
                            {
                                btn_runTask.Image = Properties.Resource.停止;
                                btn_runTask.Enabled = true;
                                btn_runTask.Text = "停止";
                            }
                            else if (state == Base.TaskRunningStatus.Stopping)
                            {
                                btn_runTask.Image = Properties.Resource.开始;
                                btn_runTask.Enabled = false;
                                btn_runTask.Text = "开始";
                            }
                            else if (state == Base.TaskRunningStatus.Stoped)
                            {
                                btn_runTask.Image = Properties.Resource.开始;
                                btn_runTask.Enabled = true;
                                btn_runTask.Text = "开始";
                            }
                        }
                    }
                }
            }));
        }

        /// <summary>
        /// 启动任务
        /// </summary>
        /// <param name="uniqueId"></param>
        private void StartTask(string uniqueId)
        {
            Service.StartTask(uniqueId);
            SetSelectRowRunningStatus(uniqueId);
        }

        /// <summary>
        /// 停止任务
        /// </summary>
        /// <param name="uniqueId"></param>
        private void StopTask(string uniqueId)
        {
            Service.StopTask(uniqueId);
            SetSelectRowRunningStatus(uniqueId);
        }

        /// <summary>
        /// 停止任务
        /// </summary>
        /// <param name="uniqueId"></param>
        /// <returns></returns>
        //private bool GetTaskIsRunning(string uniqueId)
        //{
        //    return Service.GetTaskStatus(uniqueId) == Base.TaskRunningStatus.Started;
        //}

        private TaskRunningStatus GetTaskRunningStatus(string uniqueId) => Service.GetTaskStatus(uniqueId);

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="message"></param>
        /// <param name="color"></param>
        /// <param name="memberName"></param>
        /// <param name="sourceLineNumber"></param>
        public void WriteLog(string message, bool isError = false)
        {
            if (this.IsHandleCreated)
            {
                richTextBox_Log.Invoke(new Action(() =>
                {
                    if (richTextBox_Log.GetLineFromCharIndex(richTextBox_Log.Text.Length) > 1000)
                    {
                        richTextBox_Log.Text = "";
                    }
                    richTextBox_Log.SelectionStart = richTextBox_Log.Text.Length;
                    if (isError)
                    {
                        richTextBox_Log.SelectionStart = richTextBox_Log.Text.Length;
                        richTextBox_Log.SelectionColor = Color.Red;
                        message = $"{DateTime.Now:HH:mm:ss.fff} : {message}";
                        richTextBox_Log.AppendText(message + Environment.NewLine);
                    }
                    else
                    {
                        richTextBox_Log.AppendText($"{message}\r\n");
                    }
                    richTextBox_Log.ScrollToCaret();
                }));
            }
        }

        private void 清除日志ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox_Log.Clear();
        }

        private void 导出日志ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*";
                saveFileDialog.DefaultExt = "txt";
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    File.WriteAllText(saveFileDialog.FileName, richTextBox_Log.Text);
                }
            }
        }
    }
}
